package com.atguigu.gulimall.ware.service.impl;

import com.atguigu.common.constrant.WareConstant;
import com.atguigu.gulimall.ware.entity.PurchaseDetailEntity;
import com.atguigu.gulimall.ware.service.PurchaseDetailService;
import com.atguigu.gulimall.ware.service.WareSkuService;
import com.atguigu.gulimall.ware.vo.MergeVo;
import com.atguigu.gulimall.ware.vo.PurchaseDoneVo;
import com.atguigu.gulimall.ware.vo.PurchaseItemVo;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.atguigu.common.utils.PageUtils;
import com.atguigu.common.utils.Query;

import com.atguigu.gulimall.ware.dao.PurchaseDao;
import com.atguigu.gulimall.ware.entity.PurchaseEntity;
import com.atguigu.gulimall.ware.service.PurchaseService;
import org.springframework.transaction.annotation.Transactional;


@Service("purchaseService")
public class PurchaseServiceImpl extends ServiceImpl<PurchaseDao, PurchaseEntity> implements PurchaseService {

    @Autowired
    private PurchaseDetailService purchaseDetailService;
    @Autowired
    private WareSkuService wareSkuService;


    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        QueryWrapper<PurchaseEntity> wrapper = new QueryWrapper<>();
        String key = (String)params.get("key");
        if (StringUtils.isNotBlank(key)) {
            wrapper.and(qw -> qw.eq("id", key)
                    .or().eq("assignee_id", key)
                    .or().eq("ware_id", key)
                    .or().like("assignee_name", key)
            );
        }
        IPage<PurchaseEntity> page = this.page(
                new Query<PurchaseEntity>().getPage(params),
                wrapper
        );

        return new PageUtils(page);
    }

    @Override
    public PageUtils queryPageUnReceive(Map<String, Object> params) {
        QueryWrapper<PurchaseEntity> wrapper = new QueryWrapper<>();
        wrapper.in("status", Arrays.asList("0","1"));
        IPage<PurchaseEntity> page = this.page(
                new Query<PurchaseEntity>().getPage(params),
                wrapper
        );


        return new PageUtils(page);
    }

    @Transactional
    @Override
    public void mergePurchase(MergeVo mergeVo) {
        Long purchaseId = mergeVo.getPurchaseId();
        //没勾选采购单新建一个
        if (null == purchaseId) {
            PurchaseEntity purchaseEntity = new PurchaseEntity();
            Date date = new Date();
            purchaseEntity.setCreateTime(date);
            purchaseEntity.setUpdateTime(date);
            purchaseEntity.setStatus(WareConstant.PurchaseStateEnum.CREATED.getCode());
            this.save(purchaseEntity);
            purchaseId = purchaseEntity.getId();
        }
        List<Long> items = mergeVo.getItems();
        if (null != items) {
            //中间变量，防止被修改
            Long finalPurchaseId = purchaseId;

            //需要合并的采购单状态必须是 新建 或者已分配
            QueryWrapper<PurchaseDetailEntity> wrapper = new QueryWrapper<>();
            wrapper.eq("id", items);
            List<PurchaseDetailEntity> tmpList = this.purchaseDetailService.list(wrapper);
            if (null != tmpList) {
                items = tmpList.stream().filter(item ->
                        //新建状态合并整单时是初次合并
                        WareConstant.PurchaseDetailStateEnum.CREATED.getCode() == item.getStatus() ||
                        //已分配状态合并整单是重新合并
                        WareConstant.PurchaseDetailStateEnum.ASSIGNED.getCode() == item.getStatus())
                        .map(PurchaseDetailEntity::getId).collect(Collectors.toList());

                List<PurchaseDetailEntity> entities = items.stream().map(item -> {
                    PurchaseDetailEntity entity = new PurchaseDetailEntity();
                    entity.setId(item);
                    entity.setStatus(WareConstant.PurchaseDetailStateEnum.ASSIGNED.getCode());
                    entity.setPurchaseId(finalPurchaseId);
                    return entity;
                }).collect(Collectors.toList());
                purchaseDetailService.updateBatchById(entities);
            }
        }
    }

    @Transactional
    @Override
    public void receivedPurchase(List<Long> ids) {
        //过滤出自己的新建和已分配的采购单  todo  assignee_id
        if (null != ids) {
            ArrayList<PurchaseDetailEntity> detailEntities = new ArrayList<>();
            List<PurchaseEntity> purchaseEntityList = ids.stream().map(this::getById)
                    .filter(item -> WareConstant.PurchaseStateEnum.CREATED.getCode() == item.getStatus() ||
                            WareConstant.PurchaseStateEnum.ASSIGNED.getCode() == item.getStatus())
                    .map(item -> {
                        QueryWrapper<PurchaseDetailEntity> wrapper = new QueryWrapper<>();
                        wrapper.eq("purchase_id", item.getId());
                        List<PurchaseDetailEntity> entities = this.purchaseDetailService.list(wrapper);
                        //采购项
                        List<PurchaseDetailEntity> purchaseDetailEntityList = entities.stream().map(k -> {
                            PurchaseDetailEntity purchaseDetailEntity = new PurchaseDetailEntity();
                            purchaseDetailEntity.setId(k.getId());
                            purchaseDetailEntity.setStatus(WareConstant.PurchaseDetailStateEnum.BUYING.getCode());
                            return purchaseDetailEntity;
                        }).collect(Collectors.toList());
                        detailEntities.addAll(purchaseDetailEntityList);

                        //采购单
                        PurchaseEntity purchaseEntity = new PurchaseEntity();
                        purchaseEntity.setId(item.getId());
                        purchaseEntity.setStatus(WareConstant.PurchaseStateEnum.ASSIGNED.getCode());
                        return purchaseEntity;
                    }).collect(Collectors.toList());
            //更新采购单的状态
            this.updateBatchById(purchaseEntityList);
            //更新采购需求的状态（即采购项）
            this.purchaseDetailService.updateBatchById(detailEntities);
        }
    }

    @Transactional
    @Override
    public void donePurchase(PurchaseDoneVo doneVo) {

        Long id = doneVo.getId();
        //更新采购单状态
        PurchaseEntity purchaseEntity = new PurchaseEntity();
        purchaseEntity.setId(id);
        purchaseEntity.setStatus(WareConstant.PurchaseStateEnum.FINISH.getCode());
        purchaseEntity.setUpdateTime(new Date());
        this.updateById(purchaseEntity);

        //更新采购项状态
        List<PurchaseItemVo> items = doneVo.getItems();
        if (null != items && items.size() > 0) {
            // Boolean flag = false;
            List<PurchaseDetailEntity> detailEntityList = items.stream().map(item -> {
                PurchaseDetailEntity detailEntity = new PurchaseDetailEntity();
                Long itemId = item.getItemId();
                detailEntity.setId(itemId);
                detailEntity.setStatus(item.getStatus());
                detailEntity.setReason(item.getReason());
                if (WareConstant.PurchaseDetailStateEnum.HASERROR.getCode() == item.getStatus()) {


                } else {
                    //采购正常的添加库存(此处只对采购正常的进行添加)  todo 实际采购数量不足采购数量需要具体分析
                    PurchaseDetailEntity byId = this.purchaseDetailService.getById(itemId);
                    if (null != byId) {
                        Long skuId = byId.getSkuId();
                        Long wareId = byId.getWareId();
                        Integer skuNum = byId.getSkuNum();
                        this.wareSkuService.addStock(skuId, wareId, skuNum);
                    }
                }
                return detailEntity;
            }).collect(Collectors.toList());
            this.purchaseDetailService.updateBatchById(detailEntityList);
        }
    }
}